package org.kugua.strategy.impl;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.kugua.context.CaptchaContext;
import org.kugua.dto.Captcha;
import org.kugua.enums.CaptchaEnum;
import org.kugua.enums.FontEnum;
import org.kugua.enums.QuestionAnswerType;
import org.kugua.library.QuestionAnswer;
import org.kugua.library.QuestionAnswerLibrary;
import org.kugua.library.impl.MemoryQALibrary;
import org.kugua.strategy.ParentCaptchaStrategy;
import org.springframework.core.io.ClassPathResource;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;

/**
 * 图文验证码
 * <p>
 * <li>图片中的人物是谁</li>
 * <li>问答类问题</li>
 * </p>
 *
 * @author 苦瓜
 * @create 2024-08-26
 * @since 1.0.0
 */
@Setter
@Getter
@Slf4j
public class QuestionAndAnswerCaptchaStrategy extends ParentCaptchaStrategy {

    private QuestionAnswerLibrary library = new MemoryQALibrary();

    /**
     * 验证码内容填充
     *
     * @param context 内容
     * @return Captcha
     */
    @Override
    public Captcha doFillContext(CaptchaContext context) {
        Captcha captcha = new Captcha();
        QuestionAnswer questionAnswer = library.randomOne();
        String type = questionAnswer.getType();
        String question = questionAnswer.getQuestion();
        context.setQuestionAnswerType(type);
        if (QuestionAnswerType.IMAGE_ANSWER.getType().equalsIgnoreCase(type)) {
            drawImage(question, context);
        } else {
            Graphics2D graphics = context.getGraphics();
            int fW = context.getWidth() / question.length(); // 每一个字符所占的宽度
            int fSp = (fW - (int) graphics.getFontMetrics()
                    .getStringBounds("8", graphics).getWidth()) / 2; // 字符的左右边距
            char[] charArray = question.toCharArray();
            for (int i = 0; i < question.length(); i++) {
                String s = String.valueOf(charArray[i]);
                graphics.setColor(randomColor());
                int fY = context.getHeight()
                        - ((context.getHeight() - (int) graphics.getFontMetrics()
                        .getStringBounds(s, graphics).getHeight()) >> 1); // 文字的纵坐标
                graphics.drawString(s, i * fW + fSp + 3, fY - 3);
            }
        }
        captcha.setAnswer(questionAnswer.getAnswer());
        captcha.setTooltip(questionAnswer.getTooltip());
        return captcha;
    }

    private void drawImage(String path, CaptchaContext context) {
        try {
            ClassPathResource classPathResource = new ClassPathResource(path);
            BufferedImage image = ImageIO.read(classPathResource.getInputStream());
            // 缩放
            int scaledWidth = context.getWidth();
            int scaledHeight = (int) (scaledWidth * ((double) image.getHeight() / image.getWidth()));
            context.getGraphics().drawImage(image, 0, 0, scaledWidth, scaledHeight, null);
        } catch (IOException ignored) {
            log.error("draw image failed.", ignored);
        }
    }

    /**
     * 当前验证码类型
     *
     * @return String
     */
    @Override
    public String getType() {
        return CaptchaEnum.QAC.getType();
    }

    @Override
    public Font getFont() {
        return fontProvider.get(FontEnum.NUOMITUAN.getName());
    }
}
